#-------------------------------------------------------------------------------
# Given a stem and/or a suffix (both are optional), expand into a series of
# paths of 1 to 6 directories deep. This is useful in combination with $(wildcard).

expand_tree=\
    $(filter-out *,$(foreach exp,\
        * \
        */* \
        */*/* \
        */*/*/* \
        */*/*/*/* \
        */*/*/*/*/* \
        ,$(1)/$(exp)$(2)))


#-------------------------------------------------------------------------------

# The build system will look for source code in the following folder(s)
SOURCE_ROOT?=src sr3

# This variable holds the name of every target.mak we want to build
INPUT_TARGETS:= \
	$(wildcard $(foreach root, $(sort $(SOURCE_ROOT)), \
		$(call expand_tree,$(root),target.mak) ))


# this is a repeated application of patsubst which will replace both 'src' and 'sr3'
# (to save on a lot of repeated patsubsts...)
sourcesubst=$(patsubst sr3/%,$(1),$(patsubst src/%,$(1),$(2)))


#-------------------------------------------------------------------------------
# Verbosity

V?=0# nice short name for the commandline

# This variable is used to set the verbosity if V is set to a non-zero value,
# as multiple targets will accept a -v flag (with an int argument).
# This lives here so that it will be visible in all the target.mak files in the
# source tree.
ifneq ($(strip $(V)),0)
verbosity:=-v $(V)
endif


#-------------------------------------------------------------------------------
# RULES

# Include any rules defined by the build system. These have been broken out into
# their own .mak files, to help make the build system more modular. These rules
# are included before the target list because it allows rules files to define
# functions which can be called in the target.mak files (see $(make_umbrella)
# for an example of this).
# I don't think we can control the order in which the files are included, and it
# shouldn't matter in terms of rule definitions. However, individual rules files
# should only use local variables or those defined in config.mak

include make/rules/*.mak


# We may want to extend the build system by allowing rules.mak files in the src/
# (and sr3/) directories to define rules. For experimentation, this can be
# enabled with ALLOW_SRC_RULES=1 on the command line or in userconf.mak

#ALLOW_SRC_RULES:=1
ifeq ($(call check-flag,$(ALLOW_SRC_RULES)),1)
INPUT_RULES:= \
	$(wildcard $(foreach root, $(sort $(SOURCE_ROOT)), \
		$(call expand_tree,$(root),rules.mak) ))

include $(INPUT_RULES)
endif


#-------------------------------------------------------------------------------
# AUTOGEN

# The variables AUTOGEN_TARGET_LIST, AUTOGEN_BIN_LIST and AUTOGEN_OBJ_LIST contain
# sets of generated makefiles which are included by this makefile - they are the
# magic which makes the build system work.

# AUTOGEN_TARGET_LIST is the set of dep/*/target.mak files, each one matching
# the corresponding src/*/target.mak. These files use += to add information to
# the empty variables below (TARGET et al)
AUTOGEN_TARGET_LIST:=$(foreach dir, \
	$(INPUT_TARGETS), \
	$(call sourcesubst,dep/$(TYPE)/%,$(dir)))


# Explicitly setting a few variables empty. These variables are set (using +=)
# in the autogenerated dep/*/target.mak files, using the information provided.

TARGETS:=
BIN_TARGETS:=
DLL_TARGETS:=
LIB_TARGETS:=
PDF_TARGETS:=
INCLUDES:=$(USER_INCLUDES)


# Autogen target files are included except for clean builds. This helps speed
# up cleaning the tree, and also allows a clean to proceed even if there are
# syntax errors in the target files (which can happen if a new build rule or
# target is badly defined).
ifeq ($(call check-flag,$(CLEAN)),)
include $(AUTOGEN_TARGET_LIST)
endif


#-------------------------------------------------------------------------------
# dependency post-processing

TARGETS+=$(BIN_TARGETS) $(DLL_TARGETS) $(LIB_TARGETS)

# AUTOGEN_BIN_LIST specifies a set of .d files matching each binary target.
# (using "binary" to mean output executable, dll or library)
AUTOGEN_BIN_LIST:= \
	$(BIN_TARGETS:bin/%=dep/%.d) \
	$(DLL_TARGETS:bin/%=dep/%.d) \
	$(LIB_TARGETS:lib/%=dep/%.d)

# AUTOGEN_OBJ_LIST lists the generated dependencies for each target - one matching
# each object file.
AUTOGEN_OBJ_LIST:= $(foreach target,$(TARGETS),$($(target)_DEP))


#-------------------------------------------------------------------------------
# all (the default target), will build all targets.
# Has to appear after TARGETS above.

all: $(TARGETS)


#-------------------------------------------------------------------------------
# master include target (see rules/include.mak)
# TODO: general inclusion mechanism for plugins here...
include: $(ALL_INCLUDES)


#-------------------------------------------------------------------------------
# include the second and third set of autogenerated makefiles. They get the
# benefit of being able to see all variables defined up to this point.
# These are included only if CLEAN=0 and DOCS=0 (but use $(check-flag) to
# test both vars.)

include_lists=$(and $(call check-flag,$(CLEAN)),$(call check-flag,$(DOCS)))

ifeq ($(include_lists),)
include $(AUTOGEN_BIN_LIST)
include $(AUTOGEN_OBJ_LIST)
endif


